package com.verlet.springbootdemo.controller;

import com.verlet.springbootdemo.annotation.CurrentUser;
import com.verlet.springbootdemo.annotation.IgnoreAuth;
import com.verlet.springbootdemo.annotation.Resubmit;
import com.verlet.springbootdemo.common.ServerResponse;
import com.verlet.springbootdemo.entity.User;
import com.verlet.springbootdemo.util.ThreadLocalUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author verlet
 * @date 2020/4/8
 */
@Log4j2
@RestController
@RequestMapping("/demo")
public class DemoController {

    @Value("${spring.application.name}")
    private String applicationName;

    @IgnoreAuth
    @Resubmit
    @GetMapping("/get")
    public ServerResponse<String> get(String id, HttpServletRequest request) {
        log.info("{}==>{}", applicationName, request.getRequestURI());
        return ServerResponse.createBySuccess(applicationName);
    }

    @IgnoreAuth
    @Resubmit
    @PostMapping("/postDemo")
    public ServerResponse<String> postDemo(@RequestBody Map<String, String> body) {
        body.forEach((k, v) -> log.info("{}={}", k, v));
        return ServerResponse.createBySuccess(applicationName);
    }

    @PostMapping("/post")
    public ServerResponse<String> post(@CurrentUser User user, @RequestBody Map<String, String> body) throws InterruptedException {
        body.forEach((k, v) -> log.info("{}={}", k, v));
        log.info("user=>{}", user.toString());
        String value = ThreadLocalUtil.getThreadLocalValue();
        log.info(value);
        ThreadLocalUtil.removeThreadLocal();

        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            poolExecutor.execute(() -> {
                String inheritableThreadLocalValue = ThreadLocalUtil.getInheritableThreadLocalValue();
                log.info("{}==>{}", finalI, inheritableThreadLocalValue);
            });
        }
        ThreadLocalUtil.removeInheritableThreadLocal();
        poolExecutor.shutdown();
        if (!poolExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
            poolExecutor.shutdownNow();
        }
        return ServerResponse.createBySuccess("SUCCESS");
    }
}
